package ca.cbc.panacea.elixir.service;

import ca.cbc.panacea.elixir.persistence.Transactional;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Map;

/**
 * @author : Arash Bizhanzadeh <arash.bizhanzadeh@cbc.ca>
 *         Date: 11-10-21
 *         Time: 2:27 PM
 *         CBC.ca All rights reserved.
 */

  public class AbstractJPALazyModel<T> extends LazyDataModel<T> {
    private static Logger logger = LoggerFactory.getLogger(AbstractJPALazyModel.class);
    private static final long serialVersionUID = -4327521807428362995L;

    @Inject
    private EntityManager entityManager;
    private Class<T> clazz;

    public AbstractJPALazyModel(Class<T> aClass){
        super();
        clazz = aClass;
        setPageSize(100);
    }

    @Override
    @Transactional
    public List<T> load(int first, int ps, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        logger.debug("loading lazily with page size {} and first {}", ps, first);
        logger.debug("Page size is {}", getPageSize());
        StringBuilder criteria = new StringBuilder(" 1=1 ");

        if(filters != null && filters.size()!=0){

            for (Map.Entry<String, String> e : filters.entrySet()) {
                criteria.append(" and ").append(e.getKey()).append(" like '").append(e.getValue()).append("%'    ");
            }
        }
        int pn = ((Long)entityManager.
                createQuery("select count(*) from " + clazz.getName() + " where " + criteria.toString()).getSingleResult()).intValue();
        logger.debug("number of pages is {}", pn);
        setRowCount(pn);
        StringBuilder query = new StringBuilder(" From ");
        query.append(clazz.getName()).append(" where ").append(criteria);
        if (sortField != null && !sortField.trim().equals("")) {
            if (sortOrder == SortOrder.DESCENDING) {
                query.append(" order by ").append(sortField).append(" desc");
            } else {
                query.append(" order by ").append(sortField).append(" asc");
            }
        }

        List<T> cats= (List<T>) entityManager.createQuery(query.toString()).setFirstResult(first).setMaxResults(first + ps).getResultList();
        logger.debug("cats found " + cats.size());
        return cats;

    }
}
